home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow / BaseClasses / wxdebug.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  13.1 KB  |  380 lines

  1. //------------------------------------------------------------------------------
  2. // File: WXDebug.h
  3. //
  4. // Desc: DirectShow base classes - provides debugging facilities.
  5. //
  6. // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9.  
  10. #ifndef __WXDEBUG__
  11. #define __WXDEBUG__
  12.  
  13. // This library provides fairly straight forward debugging functionality, this
  14. // is split into two main sections. The first is assertion handling, there are
  15. // three types of assertions provided here. The most commonly used one is the
  16. // ASSERT(condition) macro which will pop up a message box including the file
  17. // and line number if the condition evaluates to FALSE. Then there is the
  18. // EXECUTE_ASSERT macro which is the same as ASSERT except the condition will
  19. // still be executed in NON debug builds. The final type of assertion is the
  20. // KASSERT macro which is more suitable for pure (perhaps kernel) filters as
  21. // the condition is printed onto the debugger rather than in a message box.
  22. //
  23. // The other part of the debug module facilties is general purpose logging.
  24. // This is accessed by calling DbgLog(). The function takes a type and level
  25. // field which define the type of informational string you are presenting and
  26. // it's relative importance. The type field can be a combination (one or more)
  27. // of LOG_TIMING, LOG_TRACE, LOG_MEMORY, LOG_LOCKING and LOG_ERROR. The level
  28. // is a DWORD value where zero defines highest important. Use of zero as the
  29. // debug logging level is to be encouraged ONLY for major errors or events as
  30. // they will ALWAYS be displayed on the debugger. Other debug output has it's
  31. // level matched against the current debug output level stored in the registry
  32. // for this module and if less than the current setting it will be displayed.
  33. //
  34. // Each module or executable has it's own debug output level for each of the
  35. // five types. These are read in when the DbgInitialise function is called
  36. // for DLLs linking to STRMBASE.LIB this is done automatically when the DLL
  37. // is loaded, executables must call it explicitely with the module instance
  38. // handle given to them through the WINMAIN entry point. An executable must
  39. // also call DbgTerminate when they have finished to clean up the resources
  40. // the debug library uses, once again this is done automatically for DLLs
  41.  
  42. // These are the five different categories of logging information
  43.  
  44. enum {  LOG_TIMING = 0x01,    // Timing and performance measurements
  45.         LOG_TRACE = 0x02,     // General step point call tracing
  46.         LOG_MEMORY =  0x04,   // Memory and object allocation/destruction
  47.         LOG_LOCKING = 0x08,   // Locking/unlocking of critical sections
  48.         LOG_ERROR = 0x10,     // Debug error notification
  49.         LOG_CUSTOM1 = 0x20,
  50.         LOG_CUSTOM2 = 0x40,
  51.         LOG_CUSTOM3 = 0x80,
  52.         LOG_CUSTOM4 = 0x100,
  53.         LOG_CUSTOM5 = 0x200,
  54. };
  55.  
  56. #define LOG_FORCIBLY_SET 0x80000000
  57.  
  58. enum {  CDISP_HEX = 0x01,
  59.         CDISP_DEC = 0x02};
  60.  
  61. // For each object created derived from CBaseObject (in debug builds) we
  62. // create a descriptor that holds it's name (statically allocated memory)
  63. // and a cookie we assign it. We keep a list of all the active objects
  64. // we have registered so that we can dump a list of remaining objects
  65.  
  66. typedef struct tag_ObjectDesc {
  67.     const CHAR *m_szName;
  68.     const WCHAR *m_wszName;
  69.     DWORD m_dwCookie;
  70.     tag_ObjectDesc *m_pNext;
  71. } ObjectDesc;
  72.  
  73. #define DLLIMPORT __declspec(dllimport)
  74. #define DLLEXPORT __declspec(dllexport)
  75.  
  76. #ifdef DEBUG
  77.  
  78.     #define NAME(x) TEXT(x)
  79.  
  80.     // These are used internally by the debug library (PRIVATE)
  81.  
  82.     void WINAPI DbgInitKeyLevels(HKEY hKey, bool fTakeMax);
  83.     void WINAPI DbgInitGlobalSettings(bool fTakeMax);
  84.     void WINAPI DbgInitModuleSettings(bool fTakeMax);
  85.     void WINAPI DbgInitModuleName();
  86.     DWORD WINAPI DbgRegisterObjectCreation(
  87.         const CHAR *szObjectName, const WCHAR *wszObjectName);
  88.  
  89.     BOOL WINAPI DbgRegisterObjectDestruction(DWORD dwCookie);
  90.  
  91.     // These are the PUBLIC entry points
  92.  
  93.     BOOL WINAPI DbgCheckModuleLevel(DWORD Type,DWORD Level);
  94.     void WINAPI DbgSetModuleLevel(DWORD Type,DWORD Level);
  95.     void WINAPI DbgSetAutoRefreshLevels(bool fAuto);
  96.  
  97.     // Initialise the library with the module handle
  98.  
  99.     void WINAPI DbgInitialise(HINSTANCE hInst);
  100.     void WINAPI DbgTerminate();
  101.  
  102.     void WINAPI DbgDumpObjectRegister();
  103.  
  104.     // Display error and logging to the user
  105.  
  106.     void WINAPI DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  107.     void WINAPI DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  108.     void WINAPI DbgBreakPoint(const TCHAR *pFileName,INT iLine,const TCHAR* szFormatString,...);
  109.  
  110.     void WINAPI DbgKernelAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  111.     void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const TCHAR *pFormat,...);
  112. #ifdef UNICODE
  113.     void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const CHAR *pFormat,...);
  114.     void WINAPI DbgAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine);
  115.     void WINAPI DbgBreakPoint(const CHAR *pCondition,const CHAR *pFileName,INT iLine);
  116.     void WINAPI DbgKernelAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine);
  117. #endif
  118.     void WINAPI DbgOutString(LPCTSTR psz);
  119.  
  120.     //  Debug infinite wait stuff
  121.     DWORD WINAPI DbgWaitForSingleObject(HANDLE h);
  122.     DWORD WINAPI DbgWaitForMultipleObjects(DWORD nCount,
  123.                                     CONST HANDLE *lpHandles,
  124.                                     BOOL bWaitAll);
  125.     void WINAPI DbgSetWaitTimeout(DWORD dwTimeout);
  126.  
  127. #ifdef __strmif_h__
  128.     // Display a media type: Terse at level 2, verbose at level 5
  129.     void WINAPI DisplayType(LPTSTR label, const AM_MEDIA_TYPE *pmtIn);
  130.  
  131.     // Dump lots of information about a filter graph
  132.     void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel);
  133. #endif
  134.  
  135.     #define KASSERT(_x_) if (!(_x_))         \
  136.         DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  137.  
  138.     //  Break on the debugger without putting up a message box
  139.     //  message goes to debugger instead
  140.  
  141.     #define KDbgBreak(_x_)                   \
  142.         DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  143.  
  144.     // We chose a common name for our ASSERT macro, MFC also uses this name
  145.     // So long as the implementation evaluates the condition and handles it
  146.     // then we will be ok. Rather than override the behaviour expected we
  147.     // will leave whatever first defines ASSERT as the handler (i.e. MFC)
  148.     #ifndef ASSERT
  149.         #define ASSERT(_x_) if (!(_x_))         \
  150.             DbgAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  151.     #endif
  152.  
  153.     #define DbgAssertAligned( _ptr_, _alignment_ ) ASSERT( ((DWORD_PTR) (_ptr_)) % (_alignment_) == 0)
  154.  
  155.     //  Put up a message box informing the user of a halt
  156.     //  condition in the program
  157.  
  158.     #define DbgBreak(_x_)                   \
  159.         DbgBreakPoint(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  160.  
  161.     #define EXECUTE_ASSERT(_x_) ASSERT(_x_)
  162.     #define DbgLog(_x_) DbgLogInfo _x_
  163.     // MFC style trace macros
  164.  
  165.     #define NOTE(_x_)             DbgLog((LOG_TRACE,5,TEXT(_x_)))
  166.     #define NOTE1(_x_,a)          DbgLog((LOG_TRACE,5,TEXT(_x_),a))
  167.     #define NOTE2(_x_,a,b)        DbgLog((LOG_TRACE,5,TEXT(_x_),a,b))
  168.     #define NOTE3(_x_,a,b,c)      DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c))
  169.     #define NOTE4(_x_,a,b,c,d)    DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d))
  170.     #define NOTE5(_x_,a,b,c,d,e)  DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d,e))
  171.  
  172. #else
  173.  
  174.     // Retail builds make public debug functions inert  - WARNING the source
  175.     // files do not define or build any of the entry points in debug builds
  176.     // (public entry points compile to nothing) so if you go trying to call
  177.     // any of the private entry points in your source they won't compile
  178.  
  179.     #define NAME(_x_) ((TCHAR *) NULL)
  180.  
  181.     #define DbgInitialise(hInst)
  182.     #define DbgTerminate()
  183.     #define DbgLog(_x_) 0
  184.     #define DbgOutString(psz)
  185.     #define DbgAssertAligned( _ptr_, _alignment_ ) 0
  186.  
  187.     #define DbgRegisterObjectCreation(pObjectName)
  188.     #define DbgRegisterObjectDestruction(dwCookie)
  189.     #define DbgDumpObjectRegister()
  190.  
  191.     #define DbgCheckModuleLevel(Type,Level)
  192.     #define DbgSetModuleLevel(Type,Level)
  193.     #define DbgSetAutoRefreshLevels(fAuto)
  194.  
  195.     #define DbgWaitForSingleObject(h)  WaitForSingleObject(h, INFINITE)
  196.     #define DbgWaitForMultipleObjects(nCount, lpHandles, bWaitAll)     \
  197.                WaitForMultipleObjects(nCount, lpHandles, bWaitAll, INFINITE)
  198.     #define DbgSetWaitTimeout(dwTimeout)
  199.  
  200.     #define KDbgBreak(_x_)
  201.     #define DbgBreak(_x_)
  202.  
  203.     #define KASSERT(_x_) ((void)0)
  204.     #ifndef ASSERT
  205.     #define ASSERT(_x_) ((void)0)
  206.     #endif
  207.     #define EXECUTE_ASSERT(_x_) ((void)(_x_))
  208.  
  209.     // MFC style trace macros
  210.  
  211.     #define NOTE(_x_) ((void)0)
  212.     #define NOTE1(_x_,a) ((void)0)
  213.     #define NOTE2(_x_,a,b) ((void)0)
  214.     #define NOTE3(_x_,a,b,c) ((void)0)
  215.     #define NOTE4(_x_,a,b,c,d) ((void)0)
  216.     #define NOTE5(_x_,a,b,c,d,e) ((void)0)
  217.  
  218.     #define DisplayType(label, pmtIn) ((void)0)
  219.     #define DumpGraph(pGraph, label) ((void)0)
  220. #endif
  221.  
  222.  
  223. // Checks a pointer which should be non NULL - can be used as follows.
  224.  
  225. #define CheckPointer(p,ret) {if((p)==NULL) return (ret);}
  226.  
  227. //   HRESULT Foo(VOID *pBar)
  228. //   {
  229. //       CheckPointer(pBar,E_INVALIDARG)
  230. //   }
  231. //
  232. //   Or if the function returns a boolean
  233. //
  234. //   BOOL Foo(VOID *pBar)
  235. //   {
  236. //       CheckPointer(pBar,FALSE)
  237. //   }
  238.  
  239. // These validate pointers when symbol VFWROBUST is defined
  240. // This will normally be defined in debug not retail builds
  241.  
  242. #ifdef DEBUG
  243.     #define VFWROBUST
  244. #endif
  245.  
  246. #ifdef VFWROBUST
  247.  
  248.     #define ValidateReadPtr(p,cb) \
  249.         {if(IsBadReadPtr((PVOID)p,cb) == TRUE) \
  250.             DbgBreak("Invalid read pointer");}
  251.  
  252.     #define ValidateWritePtr(p,cb) \
  253.         {if(IsBadWritePtr((PVOID)p,cb) == TRUE) \
  254.             DbgBreak("Invalid write pointer");}
  255.  
  256.     #define ValidateReadWritePtr(p,cb) \
  257.         {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)}
  258.  
  259.     #define ValidateStringPtr(p) \
  260.         {if(IsBadStringPtr((LPCTSTR)p,INFINITE) == TRUE) \
  261.             DbgBreak("Invalid string pointer");}
  262.  
  263.     #define ValidateStringPtrA(p) \
  264.         {if(IsBadStringPtrA((LPCSTR)p,INFINITE) == TRUE) \
  265.             DbgBreak("Invalid ANSI string pointer");}
  266.  
  267.     #define ValidateStringPtrW(p) \
  268.         {if(IsBadStringPtrW((LPCWSTR)p,INFINITE) == TRUE) \
  269.             DbgBreak("Invalid UNICODE string pointer");}
  270.  
  271. #else
  272.     #define ValidateReadPtr(p,cb) 0
  273.     #define ValidateWritePtr(p,cb) 0
  274.     #define ValidateReadWritePtr(p,cb) 0
  275.     #define ValidateStringPtr(p) 0
  276.     #define ValidateStringPtrA(p) 0
  277.     #define ValidateStringPtrW(p) 0
  278. #endif
  279.  
  280.  
  281. #ifdef _OBJBASE_H_
  282.  
  283.     //  Outputting GUID names.  If you want to include the name
  284.     //  associated with a GUID (eg CLSID_...) then
  285.     //
  286.     //      GuidNames[yourGUID]
  287.     //
  288.     //  Returns the name defined in uuids.h as a string
  289.  
  290.     typedef struct {
  291.         CHAR   *szName;
  292.         GUID    guid;
  293.     } GUID_STRING_ENTRY;
  294.  
  295.     class CGuidNameList {
  296.     public:
  297.         CHAR *operator [] (const GUID& guid);
  298.     };
  299.  
  300.     extern CGuidNameList GuidNames;
  301.  
  302. #endif
  303.  
  304. #ifndef REMIND
  305.     //  REMIND macro - generates warning as reminder to complete coding
  306.     //  (eg) usage:
  307.     //
  308.     //  #pragma message (REMIND("Add automation support"))
  309.  
  310.  
  311.     #define QUOTE(x) #x
  312.     #define QQUOTE(y) QUOTE(y)
  313.     #define REMIND(str) __FILE__ "(" QQUOTE(__LINE__) ") :  " str
  314. #endif
  315.  
  316. //  Method to display objects in a useful format
  317. //
  318. //  eg If you want to display a LONGLONG ll in a debug string do (eg)
  319. //
  320. //  DbgLog((LOG_TRACE, n, TEXT("Value is %s"), (LPCTSTR)CDisp(ll, CDISP_HEX)));
  321.  
  322.  
  323. class CDispBasic
  324. {
  325. public:
  326.     CDispBasic() { m_pString = m_String; };
  327.     ~CDispBasic();
  328. protected:
  329.     PTCHAR m_pString;  // normally points to m_String... unless too much data
  330.     TCHAR m_String[50];
  331. };
  332. class CDisp : public CDispBasic
  333. {
  334. public:
  335.     CDisp(LONGLONG ll, int Format = CDISP_HEX); // Display a LONGLONG in CDISP_HEX or CDISP_DEC form
  336.     CDisp(REFCLSID clsid);      // Display a GUID
  337.     CDisp(double d);            // Display a floating point number
  338. #ifdef __strmif_h__
  339. #ifdef __STREAMS__
  340.     CDisp(CRefTime t);          // Display a Reference Time
  341. #endif
  342.     CDisp(IPin *pPin);          // Display a pin as {filter clsid}(pin name)
  343.     CDisp(IUnknown *pUnk);      // Display a filter or pin
  344. #endif // __strmif_h__
  345.     ~CDisp();
  346.  
  347.     //  Implement cast to (LPCTSTR) as parameter to logger
  348.     operator LPCTSTR()
  349.     {
  350.         return (LPCTSTR)m_pString;
  351.     };
  352. };
  353.  
  354.  
  355. #if defined(DEBUG)
  356. class CAutoTrace
  357. {
  358. private:
  359.     const TCHAR* _szBlkName;
  360.     const int _level;
  361.     static const TCHAR _szEntering[];
  362.     static const TCHAR _szLeaving[];
  363. public:
  364.     CAutoTrace(const TCHAR* szBlkName, const int level = 15)
  365.         : _szBlkName(szBlkName), _level(level)
  366.     {DbgLog((LOG_TRACE, _level, _szEntering, _szBlkName));}
  367.  
  368.     ~CAutoTrace()
  369.     {DbgLog((LOG_TRACE, _level, _szLeaving, _szBlkName));}
  370. };
  371.  
  372. #define AMTRACE(_x_) CAutoTrace __trace _x_
  373. #else
  374. #define AMTRACE(_x_)
  375. #endif
  376.  
  377. #endif // __WXDEBUG__
  378.  
  379.  
  380.